﻿using System;

namespace Trentacular.SharePoint.Util
{
    public static class ObjectUtils
    {
        public static bool NullSafeEquals<T>(T obj1, T obj2) where T : class
        {
            if (obj1 == null && obj2 == null)
                return true;

            if (obj1 == null || obj2 == null)
                return false;

            return obj1.Equals(obj2);
        }

        public static bool NullSafeEquals<T>(Nullable<T> obj1, Nullable<T> obj2) where T : struct
        {
            if (!obj1.HasValue && !obj2.HasValue)
                return true;

            if (!obj1.HasValue || !obj2.HasValue)
                return false;

            return obj1.Value.Equals(obj2.Value);
        }

        /// <summary>
        /// Checks a list of candidates for equality to a given
        /// reference value.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value">The evaluated value.</param>
        /// <param name="candidates">A list of possible values that are
        /// regarded valid.</param>
        /// <returns>True if one of the submitted <paramref name="candidates"/>
        /// matches the evaluated value. If the <paramref name="candidates"/>
        /// parameter itself is null, too, the method returns false as well,
        /// which allows to check with null values, too.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="candidates"/>
        /// is a null reference.</exception>
        public static bool Is<T>(this T value, params T[] candidates)
        {
            if (candidates == null) return false;

            foreach (var t in candidates)
            {
                if (value.Equals(t)) return true;
            }

            return false;
        }
    }
}
